<template>
  <div class="dashboard-container">
    <div class="dashboard-content">
      <!-- 左侧控制面板 -->
      <aside class="control-panel">
        <div class="control-section">
          <h3 class="section-title">数据源配置</h3>
          <div class="control-item">
            <label class="control-label">平台选择</label>
            <div class="platform-options">
              <label v-for="(platform, index) in platforms" :key="index" :class="['platform-tag', platform.value]">
                <input type="radio" v-model="selectedPlatform" :value="platform.value" />
                <span class="checkmark"></span>
                <span class="platform-name">{{ platform.label }}</span>
              </label>
            </div>
          </div>
          
          <div class="control-item">
            <label class="control-label">关键词</label>
            <input type="text" v-model="keyword" placeholder="输入搜索关键词..." class="input-box" />
          </div>
        </div>
        
        <button class="control-button" @click="startCrawler">
          <span class="button-icon">▶</span>
          <span class="button-text">开始抓取</span>
        </button>
      </aside>
      
      <!-- 主要数据展示 -->
      <main class="data-visualization">
        <!-- 数据分布 -->
        <section class="map-section card">
          <div class="section-header">
            <h2>数据分布</h2>
            <div class="section-actions">
              <button class="refresh-btn" @click="refreshData">
                <span class="refresh-icon">↻</span>
                刷新
              </button>
            </div>
          </div>
          <div class="data-distribution-container">
            <table v-if="dbInfo && dbInfo.collections.length > 0" class="data-distribution-table">
              <thead>
                <tr>
                  <th class="text-center">平台</th>
                  <th class="text-center">事件</th>
                  <th class="text-center">类型</th>
                  <th class="text-center">时间</th>
                  <th class="text-center">记录数</th>
                  <th class="text-center">存储大小</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="collection in paginatedItems" :key="collection.collectionName">
                  <td class="text-center">{{ collection.platform }}</td>
                  <td class="text-center">{{ collection.event }}</td>
                  <td class="text-center">{{ collection.type }}</td>
                  <td class="text-center">{{ collection.time }}</td>
                  <td class="text-center">{{ collection.numDocuments.toLocaleString() }}</td>
                  <td class="text-center">{{ formatSize(collection.size) }}</td>
                </tr>
                <!-- 添加空行以确保显示4行 -->
                <template v-if="paginatedItems.length < itemsPerPage">
                  <tr v-for="n in (itemsPerPage - paginatedItems.length)" :key="`empty-${n}`">
                    <td colspan="6" class="empty-row"></td>
                  </tr>
                </template>
              </tbody>
            </table>
            <div v-else class="empty-state">
              <div class="empty-icon">📊</div>
              <p>暂无数据</p>
            </div>
          </div>
          <!-- 分页按钮 -->
          <div class="pagination">
            <button 
              class="page-btn" 
              :disabled="currentPage === 1" 
              @click="currentPage--"
            >
              <span class="arrow">←</span> 上一页
            </button>
            <span class="page-info">第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
            <button 
              class="page-btn" 
              :disabled="currentPage === totalPages" 
              @click="currentPage++"
            >
              下一页 <span class="arrow">→</span>
            </button>
          </div>
        </section>
        
        <!-- 爬虫进度 -->
        <section class="crawler-progress card">
          <div class="section-header compact">
            <h2>爬虫进度</h2>
            <div class="log-actions">
              <button class="clear-btn" @click="crawlerLogs = []">
                <span class="clear-icon">×</span>
                清空
              </button>
            </div>
          </div>
          <div class="log-container">
            <div 
              v-if="crawlerLogs.length > 0" 
              class="log-content"
              ref="logContent"
            >
              <div 
                v-for="(log, index) in crawlerLogs" 
                :key="index" 
                class="log-entry"
                :class="getLogLevel(log)"
              >
                <span class="log-timestamp">{{ getCurrentTime() }}</span>
                <span class="log-message">{{ log }}</span>
              </div>
            </div>
            <div v-else class="empty-state">
              <div class="empty-icon">📝</div>
              <p>暂无日志信息</p>
            </div>
          </div>
        </section>
      </main>
    </div>
  </div>
</template>

<script>
import { config } from '../config/config';

export default {
  name: 'SpiderAnalysis',
  data() {
    return {
      platforms: [
        { label: '微博', value: 'wb' },
        { label: '知乎', value: 'zhihu' },
        { label: '小红书', value: 'xhs' },
        { label: '抖音', value: 'dy' },
        { label: '快手', value: 'ks' },
        { label: 'B站', value: 'bili' },
        { label: '贴吧', value: 'tieba' }
      ],
      selectedPlatform: '',
      keyword: '',
      dbInfo: null,
      crawlerLogs: [],
      currentPage: 1,
      itemsPerPage: 4,
    };
  },
  computed: {
    parsedCollections() {
      if (!this.dbInfo || !this.dbInfo.collections) return [];
      
      return this.dbInfo.collections.map(collection => {
        const parts = collection.collectionName.split('_');
        if (parts.length >= 4) {
          const platform = this.getPlatformName(parts[0]);
          const event = parts[1];
          const type = parts[2] === 'contents' ? '文章' : (parts[2] === 'comments' ? '评论' : parts[2]);
          const date = parts[3];
          
          return {
            ...collection,
            platform,
            event,
            type,
            time: this.formatDate(date),
            originalName: collection.collectionName
          };
        }
        
        return {
          ...collection,
          platform: collection.collectionName,
          event: '-',
          type: '-',
          time: '-',
          originalName: collection.collectionName
        };
      });
    },
    sortedCollections() {
      return [...this.parsedCollections].sort((a, b) => {
        if (a.time === '-' || b.time === '-') return 0;
        // 从原始集合名称中提取日期进行排序
        const dateA = a.originalName.split('_')[3] || '';
        const dateB = b.originalName.split('_')[3] || '';
        return dateB.localeCompare(dateA);
      });
    },
    paginatedItems() {
      if (!this.sortedCollections) return [];
      const start = (this.currentPage - 1) * this.itemsPerPage;
      const end = start + this.itemsPerPage;
      return this.sortedCollections.slice(start, end);
    },
    totalPages() {
      if (this.sortedCollections.length==0) return 1;
      return Math.ceil(this.sortedCollections.length / this.itemsPerPage);
    }
  },
  methods: {
    getPlatformName(code) {
      const platform = this.platforms.find(p => p.value === code);
      return platform ? platform.label : code;
    },
    formatDate(dateStr) {
      if (!dateStr || dateStr === '-') return '-';
      const year = dateStr.substring(0, 4);
      const month = dateStr.substring(4, 6);
      const day = dateStr.substring(6, 8);
      return `${year}年${month}月${day}日`;
    },
    formatSize(bytes) {
      if (bytes === 0) return '0 Bytes';
      const k = 1024;
      const sizes = ['Bytes', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },
    getCurrentTime() {
      const now = new Date();
      return `[${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}]`;
    },
    getLogLevel(log) {
      if (log.includes('错误') || log.includes('失败')) return 'error';
      if (log.includes('警告')) return 'warning';
      if (log.includes('完成') || log.includes('成功')) return 'success';
      return 'info';
    },
    startCrawler() {
      if (!this.selectedPlatform || !this.keyword) {
        this.crawlerLogs.push(`${this.getCurrentTime()} [错误] 请选择一个平台并输入关键词！`);
        this.scrollToBottom();
        return;
      }

      const url = `${config.baseURL}/api/v1/crawler/startCrawler`;
      const headers = { "Content-Type": "application/json" };
      const requestBody = {
        platform: this.selectedPlatform,
        keywords: this.keyword
      };

      // 清空之前的日志
      this.crawlerLogs = [];
      this.crawlerLogs.push(`${this.getCurrentTime()} [信息] 开始爬虫任务...`);
      this.scrollToBottom();

      fetch(url, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(requestBody)
      })
      .then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const reader = response.body.getReader();
        const decoder = new TextDecoder('utf-8');

        const processText = async ({ done, value }) => {
          if (done) {
            this.crawlerLogs.push(`${this.getCurrentTime()} [信息] 爬虫任务完成`);
            this.scrollToBottom();
            return;
          }
          const chunk = decoder.decode(value, { stream: true });
          // 分割多行日志
          const lines = chunk.split('\n').filter(line => line.trim());
          lines.forEach(line => {
            this.crawlerLogs.push(line);
          });
          this.scrollToBottom();
          await reader.read().then(processText);
        };

        return reader.read().then(processText);
      })
      .catch(error => {
        console.error('Error:', error);
        this.crawlerLogs.push(`${this.getCurrentTime()} [错误] 请求失败: ${error.message}`);
        this.scrollToBottom();
      });
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.logContent;
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    },
    fetchData() {
      const url = `${config.baseURL}/api/v1/crawler/getDBBase`;
      this.$http.get(url)
        .then(response => {
          if (response.data.status === 'success') {
            this.dbInfo = response.data.dbInfo;
          } else {
            console.error('获取数据失败:', response.data.message);
          }
        })
        .catch(error => {
          console.error("Error:", error);
        });
    },
    refreshData() {
      this.fetchData();
      this.crawlerLogs.push(`${this.getCurrentTime()} [信息] 刷新数据...`);
      this.scrollToBottom();
    }
  },
  mounted() {
    this.fetchData();
  }
};
</script>

<style scoped>
/* 基础样式 */
:root {
  --primary-color: #3498db;
  --secondary-color: #2ecc71;
  --danger-color: #e74c3c;
  --warning-color: #f39c12;
  --dark-bg: #1a1a2e;
  --card-bg: #16213e;
  --text-color: #000000;
  --text-muted: #b3b3b3;
  --border-color: #2a3a5a;
  --highlight-color: rgba(52, 152, 219, 0.2);
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  background-color: var(--dark-bg);
  color: black;
}

/* 仪表板容器 */
.dashboard-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background-color: var(--dark-bg);
  padding-top: 10px; /* 添加少量顶部内边距 */
  background-image: url('../background/DBack.jpg');
  background-size: cover;
  background-repeat: no-repeat;
}

.dashboard-content {
  display: flex;
  flex: 1;
  padding: 1rem 1.5rem;
  gap: 1.5rem;
}

/* 控制面板样式 */
.control-panel {
  width: 300px;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.control-section {
  background-color: white;
  border-radius: 10px;
  padding: 1.5rem;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.section-title {
  font-size: 1.2rem;
  margin-bottom: 1.2rem;
  color: black;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border-color);
}

.control-item {
  margin-bottom: 1.2rem;
}

.control-label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.95rem;
  color: black;
  font-weight: 500;
}

/* 平台选择样式 */
.platform-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
}

.platform-tag {
  color: #000;
  position: relative;
  cursor: pointer;
  display: flex;
  align-items: center;
  padding: 0.5rem 0.3rem;
  background-color: rgba(33, 170, 220, 0.7);
  border-radius: 20px;
  transition: all 0.3s ease;
  justify-content: center;
  min-width: 0;
}
/* 平台自定义颜色 */
.platform-tag.wb {
  background-color: #eea107; /* 微博 - 红色 */
}

.platform-tag.zhihu {
  background-color: #008aee; /* 知乎 - 蓝色 */
}

.platform-tag.xhs {
  background-color: #ff4d6d; /* 小红书 - 粉红色 */
}

.platform-tag.dy {
  background-color: #00c853; /* 抖音 - 绿色 */
}

.platform-tag.ks {
  background-color: #ff9800; /* 快手 - 橙色 */
}

.platform-tag.bili {
  background-color: #00a1d6; /* B站 - 蓝绿色 */
}

.platform-tag.tieba {
  background-color: #3f51b5; /* 贴吧 - 深蓝 */
}

/* 鼠标悬停统一效果 */
.platform-tag:hover {
  background-color: rgba(174, 166, 166);
}

.platform-tag input[type="radio"] {
  position: absolute;
  opacity: 0;
  cursor: pointer;
}

.checkmark {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: 6px;
  background-color: transparent;
  border: 2px solid black;
  border-radius: 50%;
  transition: all 0.3s ease;
  flex-shrink: 0;
}

.platform-tag input[type="radio"]:checked ~ .checkmark {
  background-color: var(--primary-color);
  border-color: var(--primary-color);
}

.platform-tag input[type="radio"]:checked ~ .checkmark::after {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  margin: 2px;
  border-radius: 50%;
  background-color: rgb(0, 0, 0);
}

.platform-name {
  font-size: 0.85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 输入框样式 */
.input-box {
  width: 100%;
  padding: 0.8rem 1rem;
  background-color: rgba(255, 255, 255, 0.1);
  border: 2px solid black;
  border-radius: 6px;
  color: black;
  font-size: 0.95rem;
  transition: all 0.3s ease;
}

.input-box:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px var(--highlight-color);
}

.input-box::placeholder {
  color: var(--text-muted);
}

/* 按钮样式 */
.control-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  padding: 1rem;
  background: linear-gradient(90deg, #007cf0 0%, #00dfd8 100%);
  color: rgb(255, 255, 255);
  border: none;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
}

.control-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
}

.control-button:active {
  transform: translateY(0);
}

.button-icon {
  font-size: 1.1rem;
}

.button-text {
  flex: 1;
  text-align: center;
}

/* 数据可视化区域 */
.data-visualization {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.card {
  background-color: white;
  border-radius: 10px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.2rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid var(--border-color);
}

/* 爬虫进度标题紧凑样式 */
.section-header.compact {
  margin-bottom: 0.5rem;
  padding-bottom: 0.5rem;
}

.section-header h2 {
  font-size: 1.3rem;
  color: black;
}

.section-actions {
  display: flex;
  gap: 0.5rem;
}

.refresh-btn, .clear-btn, .page-btn {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.5rem 1rem;
  background-color: rgba(255, 255, 255, 0.1);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  color: black;
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.3s ease;
}

.refresh-btn{
  background-color: rgba(43, 186, 18, 0.7)
}

.clear-btn{ 
  background-color: rgba(255, 0, 0, 0.7)
} 

.refresh-btn:hover, .clear-btn:hover, .page-btn:hover {
  background-color: rgb(175, 183, 175);
}

.refresh-icon, .clear-icon {
  font-size: 1rem;
}

/* 数据分布表格 */
.data-distribution-container {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 1rem;
  background-color: #0a0f1a;
}

.data-distribution-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.data-distribution-table th {
  position: sticky;
  top: 0;
  background-color: var(--card-bg);
  padding: 0.8rem 0.5rem;
  font-weight: 600;
  color: var(--primary-color);
  border-bottom: 2px solid var(--border-color);
  z-index: 1;
}

.data-distribution-table td {
  padding: 0.8rem 0.5rem;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.9rem;
}

/* 表格内容居中 */
.text-center {
  text-align: center;
}

.data-distribution-table tr:last-child td {
  border-bottom: none;
}

.data-distribution-table tr:hover td {
  background-color: rgba(255, 255, 255, 0.05);
}

.empty-row {
  height: 3rem;
}

/* 分页样式 */
.pagination {
  color: #000;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
}

.page-btn {
  color: white;
  background: linear-gradient(90deg, #007cf0 0%, #00b6df 100%);
  min-width: 90px;
}

.page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.page-info {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.arrow {
  font-size: 1rem;
}

/* 空状态样式 */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: black;
  padding: 2rem 0;
  background-color: rgb(255, 255, 255);
}

.empty-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
  opacity: 0.5;
}

.empty-state p {
  font-size: 1rem;
}

/* 爬虫日志样式 */
.crawler-progress {
  flex: 1;
  min-height: 300px;
}

.log-container {
  height: 300px;
  display: flex;
  flex-direction: column;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  overflow: hidden;
}

.log-content {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.85rem;
  line-height: 1.5;
  background-color: #0a0f1a;
  border-radius: 6px;
  max-height: 100%;
}

.log-entry {
  margin-bottom: 0.3rem;
  word-break: break-all;
  padding: 0.3rem 0.5rem;
  border-radius: 3px;
  display: flex;
}

.log-timestamp {
  color: var(--text-muted);
  margin-right: 0.5rem;
  flex-shrink: 0;
}

.log-message {
  color: var(--text-color);
  white-space: pre-wrap;
}

/* 日志级别样式 */
.log-entry.info {
  background-color: rgba(52, 152, 219, 0.1);
  border-left: 3px solid var(--primary-color);
}

.log-entry.success {
  background-color: rgba(46, 204, 113, 0.1);
  border-left: 3px solid var(--secondary-color);
}

.log-entry.warning {
  background-color: rgba(243, 156, 18, 0.1);
  border-left: 3px solid var(--warning-color);
}

.log-entry.error {
  background-color: rgba(231, 76, 60, 0.1);
  border-left: 3px solid var(--danger-color);
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.2);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .dashboard-content {
    flex-direction: column;
  }
  
  .control-panel {
    width: 100%;
  }
  
  .data-visualization {
    width: 100%;
  }
}

@media (max-width: 768px) {
  .dashboard-content {
    padding: 1rem;
  }
  
  .platform-options {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* 表格样式优化 */
.data-distribution-table th,
.data-distribution-table td {
  padding: 0.8rem 0.5rem;
  font-size: 0.9rem;
}

.data-distribution-table th {
  background-color: var(--card-bg);
  font-weight: 600;
  color: var(--primary-color);
  white-space: nowrap;
}

.data-distribution-table td {
  color: var(--text-color);
}

/* 确保表格内容不会换行 */
.data-distribution-table td.text-center {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 120px;
}

/* 添加表格行悬停效果 */
.data-distribution-table tbody tr:hover {
  background-color: rgba(255, 255, 255, 0.05);
  transition: background-color 0.2s ease;
}

</style>